博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
crm02 stark组件(自定义Django-admin)之运行流程
阅读量:4695 次
发布时间:2019-06-09

本文共 38493 字,大约阅读时间需要 128 分钟。

项目目录结构:                    

   

 

 

 

 

配置文件加载 setting.py  会从上至下加载每个app的app.py文件

 

第一步:循环加载执行所有已经注册的app中的stark.py文件

###### app01/app.py ###### from django.apps import AppConfigclass App01Config(AppConfig):    name = 'app01'###### app02/app.py ###### from django.apps import AppConfigclass App02Config(AppConfig):    name = 'app02'###### stark/app.py ###### from django.apps import AppConfigfrom django.utils.module_loading import autodiscover_modulesclass StarkConfig(AppConfig):    name = 'stark'    def ready(self):  #ready方法在加载的时候会执行        autodiscover_modules('stark') # 扫描加载所有已经注册的app中的stark.py文件

 

第二步: 执行代码

###### app01/stark.py ######from stark.service.sites import site,ModelStarkfrom .models import *from django.utils.safestring import mark_safeclass BookConfig(ModelStark):    #自定义列    def show_authors(self,obj=None,header=False):        if header:            return "作者信息"        return " ".join([author.name for author in obj.authors.all()])    list_display=["title","price","state","publish",show_authors]site.register(Book,BookConfig)site.register(Publish)print(site._registry)###### app02/stark.py ######print("234")

 

第三步 所有的app中的stark.py里面 都是调用 stark/service/sites.py 的site

这里应用的是一个单例模式,对于StarkSite类的一个单例模式,执行的每一个app中的每一个site都是同一个实例对象

 

第四步 执行register方法(代码在第二步里面)

site.register(Book,BookConfig)site.register(Publish)
class StarkSite:    '''    stark全局类    '''    def __init__(self):        self._registry = {}    def register(self, model, admin_class=None, **options):        admin_class = admin_class or ModelStark        self._registry[model] = admin_class(model)

 

思考:在每一个app的admin .py中加上

print(site._registry) # 执行结果{模型对象:配置类对象(模型类名)}? {
:
,
:
}

 

到这里,注册结束!

 

 

 

<5> admin的URL配置

urlpatterns = [    url(r'^admin/', admin.site.urls),]
class AdminSite(object):         def get_urls(self):        from django.conf.urls import url, include              urlpatterns = []        # Add in each model's views, and create a list of valid URLS for the        # app_index        valid_app_labels = []        for model, model_admin in self._registry.items():            urlpatterns += [                url(r'^%s/%s/' % (model._meta.app_label, model._meta.model_name), include(model_admin.urls)),            ]            if model._meta.app_label not in valid_app_labels:                valid_app_labels.append(model._meta.app_label)              return urlpatterns    @property    def urls(self):        return self.get_urls(), 'admin', self.name

<6>  url()方法的扩展应用

from django.shortcuts import HttpResponsedef test01(request):    return HttpResponse("test01")def test02(request):    return HttpResponse("test02")urlpatterns = [    url(r'^admin/', admin.site.urls),    url(r'^yuan/', ([                    url(r'^test01/', test01),                    url(r'^test02/', test02),                    ],None,None)),]

扩展优化

 

 

 

 

全代码01版

# -*- coding: utf-8 -*-# @Time    : 2019/4/12 11:51# @Author  : xxx# @Email   : xxx@admin.com# @File    : sites.py# @Software: PyCharmfrom django.urls import path,re_pathfrom django.shortcuts import HttpResponse,renderfrom app01.models import *from django.utils.safestring import mark_safefrom django.urls import reverseclass ModelStark(object):    '''    默认配置类    '''    list_display=("__str__",)    def __init__(self,model):  #self  当前访问模型表对应的配置类对象 eg:
self.model=model #self.model 当前访问模型表 eg:
self.model_name = self.model._meta.model_name #模型表的名字 eg:book self.app_label = self.model._meta.app_label #app的名字 eg:app01 # 反向解析当前访问表的增删改查URL def get_list_url(self): # 反向解析当前表的删除的URL list_url = reverse("%s_%s_list" % (self.app_label, self.model_name)) return list_url def get_add_url(self,obj): # 反向解析当前表的删除的URL add_url = reverse("%s_%s_delete" % (self.app_label, self.model_name)) return add_url def get_delete_url(self,obj): # 反向解析当前表的删除的URL delete_url = reverse("%s_%s_delete" % (self.app_label, self.model_name), args=(obj.pk,)) return delete_url def get_change_url(self, obj): # 反向解析当前表的删除的URL change_url = reverse("%s_%s_change" % (self.app_label, self.model_name), args=(obj.pk,)) return change_url # 三个默认列 def show_checkbox(self, obj=None, header=False): if header: return mark_safe("
") return mark_safe("
") def show_delbtn(self, obj=None, header=False): if header: return "删除" return mark_safe("
删除"%self.get_delete_url(obj)) def show_editbtn(self, obj=None, header=False): if header: return "编辑" return mark_safe("
编辑" %self.get_change_url(obj)) # 构建新的list_display def get_new_list_display(self): temp=[] temp.extend(self.list_display) temp.append(ModelStark.show_editbtn) temp.append(ModelStark.show_delbtn) temp.insert(0,ModelStark.show_checkbox) return temp # 视图函数 def list_view(self,request): ''' self: 当前访问模型表对应的配置类对象 self.model: 当前访问模型表 :param request: :return: ''' queryset=self.model.objects.all() print(queryset) #eg:
,
]> print(self.list_display) # eg:['title', 'price', 'state', 'publish',
] print(self.get_new_list_display()) #[
, 'title', 'price', 'state', 'publish',
,
,
] # 构建表头 header_list=[] for field_or_func in self.get_new_list_display(): if callable(field_or_func): val=field_or_func(self,header=True) header_list.append(val) #header_list.append(field_or_func.__name__) else: if field_or_func=="__str__": val=self.model._meta.model_name.upper() print(val) else: field_obj = self.model._meta.get_field(field_or_func) val=field_obj.verbose_name header_list.append(val) # 构建展示数据 new_data=[] for obj in queryset: temp=[] for field_or_func in self.get_new_list_display(): # if callable(field_or_func): # field:方法 val=field_or_func(self,obj) else: try: # field:字符串 from django.db.models.fields.related import ManyToManyField field_obj=self.model._meta.get_field(field_or_func) # 判断是否多对多字段 if type(field_obj)==ManyToManyField: raise Exception("list_display不能是多对多字段!") # 判断字段是否 拥有choices属性 if field_obj.choices: val=getattr(obj,"get_%s_display"%field_or_func)() else: val=getattr(obj,field_or_func) except Exception as e: #val=obj val=getattr(obj,field_or_func)() #如果没有自定义配置类 就会采用默认配置类ModelStark 此时就会getattr(obj,__str__)() obj是模型类 temp.append(val) new_data.append(temp) print("new_data",new_data) #new_data [["
", 'python', Decimal('123.00'), '已出版',
, 'alex egon', "
编辑", "
删除"], # ["
", 'java', Decimal('234.00'), '已出版',
, 'egon', "
编辑", "
删除"]] ''' 目标数据结构 new_data=[ ["python",123], ["java",234] ] ''' return render(request,'stark/list_view.html',locals()) def add_view(self,request): return HttpResponse("add_view") def change_view(self,request, id): return HttpResponse("change_view") def delete_view(self,request, id): return HttpResponse("delete_view") @property def get_urls(self): temp = [ path("", self.list_view,name="%s_%s_list"%(self.app_label,self.model_name)), path("add/", self.add_view,name="%s_%s_add"%(self.app_label,self.model_name)), re_path("(\d+)/change/", self.change_view,name="%s_%s_change"%(self.app_label,self.model_name)), re_path("(\d+)/delete/", self.delete_view,name="%s_%s_delete"%(self.app_label,self.model_name)), ] return (temp, None, None)class StarkSite: ''' stark全局类 ''' def __init__(self): self._registry = {} def register(self, model, admin_class=None, **options): admin_class = admin_class or ModelStark self._registry[model] = admin_class(model) def get_urls(self): # 动态为注册的模型类创建增删改查URL temp = [] # {Book:ModelAdmin(Book),Publish:ModelAdmin(Publish)} for model, config_obj in self._registry.items(): print("---->", model, config_obj) model_name = model._meta.model_name app_label = model._meta.app_label temp.append( path("%s/%s/" % (app_label,model_name),config_obj.get_urls) ) ''' path("stark/app01/book",BookConfig(Book).list_view) path("stark/app01/book/add",BookConfig(Book).add_view) path("stark/app01/publish",ModelAdmin(Publish).list_view) path("stark/app01/publish/add",ModelAdmin(Publish).add_view) ''' return temp @property def urls(self): return self.get_urls(),None,Nonesite = StarkSite()
stark/service/sites.py
# -*- coding: utf-8 -*-# @Time    : 2019/4/12 11:47# @Author  : xxx# @Email   : xxx@admin.com# @File    : stark.py# @Software: PyCharmfrom stark.service.sites import site,ModelStarkfrom .models import *from django.utils.safestring import mark_safeclass BookConfig(ModelStark):    def show_authors(self,obj=None,header=False):        if header:            return "作者信息"        return " ".join([author.name for author in obj.authors.all()])    list_display=["title","price","state","publish",show_authors]site.register(Book,BookConfig)site.register(Publish)print(site._registry)
app01/stark.py
from django.db import models# Create your models here.class Author(models.Model):    nid = models.AutoField(primary_key=True)    name=models.CharField( max_length=32)    age=models.IntegerField()    def __str__(self):        return self.nameclass Publish(models.Model):    nid = models.AutoField(primary_key=True)    name=models.CharField( max_length=32)    city=models.CharField( max_length=32)    email=models.EmailField()    def __str__(self):        return self.nameclass Book(models.Model):    nid = models.AutoField(primary_key=True)    title = models.CharField( max_length=32,verbose_name="书籍名称")    # publishDate=models.DateField()    price=models.DecimalField(max_digits=5,decimal_places=2,verbose_name="价格")    state=models.IntegerField(choices=[(1,"已出版"),(2,"未出版社")],default=1)    # 与Publish建立一对多的关系,外键字段建立在多的一方    publish=models.ForeignKey(to="Publish",to_field="nid",on_delete=models.CASCADE)    # 与Author表建立多对多的关系,ManyToManyField可以建在两个模型中的任意一个,自动创建第三张表    authors=models.ManyToManyField(to='Author',)    def __str__(self):        return self.title
app01/models.py
from django.contrib import adminfrom django.urls import pathfrom stark.service.sites import siteurlpatterns = [    path('admin/', admin.site.urls),    path('stark/', site.urls),]
urls.py
    
Title

查看数据

{% for item in header_list %}
{% endfor %}
{% for item in new_data %}
{% for info in item %}
{% endfor %}
{% endfor %}
{ { item }}
{ { info }}
stark/templates/stark/list_view.html
# -*- coding: utf-8 -*-# @Time    : 2019/4/12 11:48# @Author  : xxx# @Email   : xxx@admin.com# @File    : stark.py# @Software: PyCharmprint("234")
app02/stark.py

 

 

全代码02版 增删改查  ModelForm

# -*- coding: utf-8 -*-# @Time    : 2019/4/12 11:51# @Author  : xxx# @Email   : xxx@admin.com# @File    : sites.py# @Software: PyCharmfrom django.urls import path,re_pathfrom django.shortcuts import HttpResponse,render,redirectfrom app01.models import *from django.utils.safestring import mark_safefrom django.core.exceptions import FieldDoesNotExistfrom django.urls import reverseclass ModelStark(object):    '''    默认配置类    '''    list_display=("__str__",)    list_display_links = []    model_form_class=None    def __init__(self,model):        self.model=model        self.model_name = self.model._meta.model_name        self.app_label = self.model._meta.app_label    # 反向解析当前访问表的增删改查URL    def get_list_url(self):        # 反向解析当前表的删除的URL        list_url = reverse("%s_%s_list" % (self.app_label, self.model_name))        return list_url    def get_add_url(self):        # 反向解析当前表的删除的URL        add_url = reverse("%s_%s_add" % (self.app_label, self.model_name))        return add_url    def get_delete_url(self,obj):        # 反向解析当前表的删除的URL        delete_url = reverse("%s_%s_delete" % (self.app_label, self.model_name), args=(obj.pk,))        return delete_url    def get_change_url(self, obj):        # 反向解析当前表的删除的URL        change_url = reverse("%s_%s_change" % (self.app_label, self.model_name), args=(obj.pk,))        return change_url    # 三个默认列    def show_checkbox(self, obj=None, header=False):        if header:            return mark_safe("")        return mark_safe("")    def show_delbtn(self, obj=None, header=False):        if header:            return "删除"        return mark_safe("删除"%self.get_delete_url(obj))    def show_editbtn(self, obj=None, header=False):        if header:            return "编辑"        return mark_safe("编辑" %self.get_change_url(obj))    #  构建新的list_display    def get_new_list_display(self):        temp=[]        temp.extend(self.list_display)        temp.append(ModelStark.show_editbtn)        temp.append(ModelStark.show_delbtn)        temp.insert(0,ModelStark.show_checkbox)        return temp    #  视图函数    def list_view(self,request):        '''        self: 当前访问模型表对应的配置类对象        self.model: 当前访问模型表        :param request:        :return:        '''        queryset=self.model.objects.all()        print(queryset)        print(self.list_display) # ["title","price"]        #   构建表头        header_list=[]        for field_or_func in self.get_new_list_display():            if callable(field_or_func):                val=field_or_func(self,header=True)                header_list.append(val)                #header_list.append(field_or_func.__name__)            else:                 if field_or_func=="__str__":                     val=self.model._meta.model_name.upper()                     print(val)                 else:                      field_obj = self.model._meta.get_field(field_or_func)                      val=field_obj.verbose_name                 header_list.append(val)        #  构建展示数据        new_data=[]        for obj in queryset:            temp=[]            for field_or_func in self.get_new_list_display(): # ["title","price","state","publish",show_authors]                if callable(field_or_func):                    #  field:方法                    val=field_or_func(self,obj)                else:                    try:                        #  field:字符串                        from django.db.models.fields.related import ManyToManyField                        field_obj=self.model._meta.get_field(field_or_func)                        #  判断是否多对多字段                        if type(field_obj)==ManyToManyField:                            raise Exception("list_display不能是多对多字段!")                        #  判断字段是否 拥有choices属性                        if field_obj.choices:                            val=getattr(obj,"get_%s_display"%field_or_func)()                        else:                            val=getattr(obj,field_or_func)                            if field_or_func in  self.list_display_links:                                val=mark_safe("%s"%(self.get_change_url(obj),val))                    except FieldDoesNotExist as e:                        #val=obj                        val=getattr(obj,field_or_func)()                temp.append(val)            new_data.append(temp)        print("new_data",new_data) # [['python', Decimal('123.00')], ['java', Decimal('234.00')]]        '''        目标数据结构        new_data=[            ["python",123],            ["java",234]        ]        '''        #  相关变量        table_name=self.model._meta.verbose_name        add_url=self.get_add_url()        return render(request,'stark/list_view.html',locals())    def get_model_form(self):        from django.forms import ModelForm        class BaseModelForm(ModelForm):            class Meta:                model = self.model                fields = "__all__"        return self.model_form_class or BaseModelForm    def add_view(self,request):        BaseModelForm=self.get_model_form()        if  request.method=="GET":            form_obj=BaseModelForm()            return render(request,"stark/add_view.html",locals())        else:            form_obj = BaseModelForm(request.POST)            if form_obj.is_valid():                form_obj.save()                return redirect(self.get_list_url())            else:                return render(request, "stark/add_view.html", locals())    def change_view(self,request,id):        BaseModelForm=self.get_model_form()        edit_obj=self.model.objects.filter(pk=id).first()        if  request.method=="GET":            form_obj=BaseModelForm(instance=edit_obj)            return render(request,"stark/change_view.html",locals())        else:            form_obj = BaseModelForm(request.POST,instance=edit_obj)            if form_obj.is_valid():                form_obj.save()                return redirect(self.get_list_url())            else:                return render(request, "stark/change_view.html", locals())    def delete_view(self,request, id):        if request.method=="POST":            self.model.objects.filter(pk=id).delete()            return redirect(self.get_list_url())        list_url=self.get_list_url()        return render(request,"stark/delete_view.html",locals())    @property    def get_urls(self):        temp = [            path("", self.list_view,name="%s_%s_list"%(self.app_label,self.model_name)),            path("add/", self.add_view,name="%s_%s_add"%(self.app_label,self.model_name)),            re_path("(\d+)/change/", self.change_view,name="%s_%s_change"%(self.app_label,self.model_name)),            re_path("(\d+)/delete/", self.delete_view,name="%s_%s_delete"%(self.app_label,self.model_name)),        ]        return (temp, None, None)class StarkSite:    '''    stark全局类    '''    def __init__(self):        self._registry = {}    def register(self, model, admin_class=None, **options):        admin_class = admin_class or ModelStark        self._registry[model] = admin_class(model)    def get_urls(self):        #  动态为注册的模型类创建增删改查URL        temp = []        # {Book:ModelAdmin(Book),Publish:ModelAdmin(Publish)}        for model, config_obj in self._registry.items():            print("---->", model, config_obj)            model_name = model._meta.model_name            app_label = model._meta.app_label            temp.append(                path("%s/%s/" % (app_label,model_name),config_obj.get_urls)            )        '''           path("stark/app01/book",BookConfig(Book).list_view)           path("stark/app01/book/add",BookConfig(Book).add_view)                 path("stark/app01/publish",ModelAdmin(Publish).list_view)           path("stark/app01/publish/add",ModelAdmin(Publish).add_view)                '''        return temp    @property    def urls(self):        return self.get_urls(),None,Nonesite = StarkSite()
stark/service/sites.py
# -*- coding: utf-8 -*-# @Time    : 2019/4/12 11:47# @Author  : xxx# @Email   : xxx@admin.com# @File    : stark.py# @Software: PyCharmfrom stark.service.sites import site,ModelStarkfrom .models import *from django.utils.safestring import mark_safefrom django.forms import ModelFormclass BookModelForm(ModelForm):    class Meta:        model=Book        fields="__all__"        error_messages={           "title":{ "required":" 该字段不能为空!"}        }class BookConfig(ModelStark):    def show_authors(self,obj=None,header=False):        if header:            return "作者信息"        return " ".join([author.name for author in obj.authors.all()])    list_display=["title","price","state","publish",show_authors]    list_display_links=["title","price"]    model_form_class=BookModelFormsite.register(Book,BookConfig)site.register(Publish)print(site._registry)
app01/stark.py
    
Title

查看数据

添加{
{ table_name }}
{% for item in header_list %}
{% endfor %}
{% for item in new_data %}
{% for info in item %}
{% endfor %}
{% endfor %}
{ { item }}
{ { info }}
stark/templates/stark/list_view.html
    
Title

添加数据

{% include "stark/form.html" %}
stark/templates/stark/add_view.html
    
Title

编辑数据

{% include "stark/form.html" %}
stark/templates/stark/change_view.html
    
Title
{% csrf_token %}
取消
stark/templates/stark/delete_view.html
{% csrf_token %} {% for field in form_obj %}
{
{ field }}
{ { field.errors.0 }}
{% endfor %}
stark/templates/stark/form.html

 

 

全代码03版 增删改查  ModelForm 分页 筛选框

# -*- coding: utf-8 -*-# @Time    : 2019/4/12 11:51# @Author  : xxx# @Email   : xxx@admin.com# @File    : sites.py# @Software: PyCharmfrom django.urls import path,re_pathfrom django.shortcuts import HttpResponse,render,redirectfrom app01.models import *from django.utils.safestring import mark_safefrom django.core.exceptions import FieldDoesNotExistfrom django.urls import reverseclass ShowList(object):    def __init__(self,request,config_obj,queryset):        self.config_obj=config_obj  #当前模型配置类对象  eg:BookConfig(Book) 默认是ModelStark(Book)        self.queryset=queryset #符合条件queryset字典数据记录        self.request=request #请求        self.pager_queryset=self.get_pager_queryset()  #类实例化时执行分页函数 获取当前页的数据    def get_pager_queryset(self):        from stark.utils.page import Pagination        current_page = self.request.GET.get("page", 1)        self.pagination = Pagination(self.request, current_page, self.queryset, per_page_num=self.config_obj.per_page_num or 5)        # per_page_num=self.config_obj.per_page_num or 5 eg:模型配置类里面(BookConfig(Book))自定义下标个数 没有定义就用5        queryset = self.queryset[self.pagination.start:self.pagination.end] #获取当前页的所有数据切片        return queryset    def get_header(self):        '''        获取表头        :return:        '''        #   构建表头        header_list = []        for field_or_func in self.config_obj.get_new_list_display():            if callable(field_or_func): #如果时可调用的函数                val = field_or_func(self.config_obj, header=True)  #eg: def show_delbtn(self,obj=None, header=False):pass  ---self =self.config_obj,obj=None,header=True                header_list.append(val)                # header_list.append(field_or_func.__name__)            else:                if field_or_func == "__str__":  #如果没有自定义list_display  则默认只有三个函数列  +                    val = self.config_obj.model._meta.model_name.upper() #eg:BookConfig(Book).Book._meta.model_name.upper() = 'book'.upper()                    print(val)                else:                    field_obj = self.config_obj.model._meta.get_field(field_or_func)  #得到模型类的每个字段类的实例对象                    val = field_obj.verbose_name #当field_obj有verbose_name属性时则用verbose_name ,无则用字段类的实例对象名(字段名) eg:price、state、publish                header_list.append(val)        return header_list    def get_body(self):        '''        获取标体        :return:        '''        #  构建展示数据        new_data = []        for obj in self.pager_queryset:            temp = []            for field_or_func in self.config_obj.get_new_list_display():  # ["title","price","state","publish",show_authors]                if callable(field_or_func):                    #  field:方法                    val = field_or_func(self.config_obj, obj)  #obj为queryset字段的对象                else:                    try:                        #  field:字符串                        from django.db.models.fields.related import ManyToManyField                        field_obj = self.config_obj.model._meta.get_field(field_or_func)                        #  判断是否多对多字段                        if type(field_obj) == ManyToManyField:                            raise Exception("list_display不能是多对多字段!")                        #  判断字段是否 拥有choices属性                        if field_obj.choices:                            val = getattr(obj, "get_%s_display" % field_or_func)()  #模型类(有一个eg:get_state_display(self)方法来处理拥有choices属性的字段)实例对象                        else:                            val = getattr(obj, field_or_func)                            if field_or_func in self.config_obj.list_display_links:  #模型配置类自定义list_display_links  #可以链接到编辑页面                                val = mark_safe("%s" % (self.config_obj.get_change_url(obj), val))                    except FieldDoesNotExist as e:                        # val=obj                        val = getattr(obj, field_or_func)()                temp.append(val)            new_data.append(temp)        print("new_data", new_data)        '''        new_data [["", "python180", "123.00", '已出版', 
, 'alex egon', "
编辑", "
删除"], ["
", "
java", "
234.00", '已出版',
, 'egon', "
编辑", "
删除"], ["
", "
挤奶龙爪手123", "
180.00", '已出版',
, 'egon', "
编辑", "
删除"]] 目标数据结构 new_data=[ ["python",123], ["java",234] ] ''' return new_dataclass ModelStark(object): ''' 默认配置类 ''' list_display=("__str__",) # 自定义显示哪些字段 list_display_links = [] #自定义 哪些字段 可以链接编辑 model_form_class=None #自定义model form模型表单类 per_page_num=None #分页 自定义每页显示的数据记录条数 search_fields=[] #自定义可以筛选框可以采用哪些值筛选 search_val=None #用户输入的筛选框的值 def __init__(self,model): self.model=model # 模型类 eg: Book、Publish等 # self.model._meta 默认生成的表名 应用名.模型类名小写 eg: app01.book self.model_name = self.model._meta.model_name# self.model._meta.model_name <---->Book._meta.model_name <------>模型类名小写 book self.app_label = self.model._meta.app_label#app名 eg: self.model._meta.app_label = app01 # 反向解析当前访问表的增删改查URL def get_list_url(self): # 反向解析当前表的删除的URL list_url = reverse("%s_%s_list" % (self.app_label, self.model_name)) return list_url def get_add_url(self): # 反向解析当前表的删除的URL add_url = reverse("%s_%s_add" % (self.app_label, self.model_name)) return add_url def get_delete_url(self,obj): # 反向解析当前表的删除的URL delete_url = reverse("%s_%s_delete" % (self.app_label, self.model_name), args=(obj.pk,)) return delete_url def get_change_url(self, obj): # 反向解析当前表的删除的URL change_url = reverse("%s_%s_change" % (self.app_label, self.model_name), args=(obj.pk,)) return change_url # 三个默认列 def show_checkbox(self, obj=None, header=False): if header: return mark_safe("
") #将字符串转换成前端html标签 return mark_safe("
") def show_delbtn(self, obj=None, header=False): if header: return "删除" return mark_safe("
删除"%self.get_delete_url(obj)) def show_editbtn(self, obj=None, header=False): if header: return "编辑" return mark_safe("
编辑" %self.get_change_url(obj)) # 构建新的list_display def get_new_list_display(self): temp=[] temp.extend(self.list_display)#迭代对象循环添加进去 temp.append(ModelStark.show_editbtn) #编辑按钮 temp.append(ModelStark.show_delbtn) #删除按钮 temp.insert(0,ModelStark.show_checkbox) #复选框 return temp def get_search_condition(self,val): # val = request.GET.get("q") #获取前端页面搜索框里面 name为q的values # print(val) from django.db.models import Q q = Q() # if val: #如果用户在搜索框 输入值 self.search_val = val q.connector = "or" #实现或操作 并 for field in self.search_fields: # ["title","price"] #在app01/stark.py可以自定义 搜索的数据库的字段 print(field) # queryset=queryset.filter(Q(title__contains=val)|Q(price__contains=val)) q.children.append((field + "__contains", val))#把条件追加进去 # else: # self.search_val=None # # print(q) #(AND: ) 没有用户搜索值时 return q #把搜索条件返回 eg: 相当于 q = Q(title__contains=val)|Q(price__contains=val) # 视图函数 查 def list_view(self,request): ''' self: 当前访问模型表对应的配置类对象 self.model: 当前访问模型表 :param request: :return: ''' queryset=self.model.objects.all() #获取 # search过滤 val = request.GET.get("q") if val: #判断是有筛选框传值 queryset=queryset.filter(self.get_search_condition(val)) #调用过滤类方法 传值request else: self.search_val = None #将上次筛选框的值清空 show_list=ShowList(request,self,queryset) #self eg: BookConfig(ModelStark)实例对象 # 相关变量 table_name=self.model._meta.verbose_name #模型表 verbose_name 注释 add_url=self.get_add_url() #获取添加数据的urls return render(request,'stark/list_view.html',locals())#判断app01/stark.py是否有传了model_form_class(自定义模型表单类) 没有就使用BaseModelForm 用在增、改两个视图 def get_model_form(self): from django.forms import ModelForm class BaseModelForm(ModelForm): class Meta: model = self.model fields = "__all__" return self.model_form_class or BaseModelForm # 视图函数 增 def add_view(self,request): BaseModelForm=self.get_model_form() if request.method=="GET": form_obj=BaseModelForm() return render(request,"stark/add_view.html",locals()) else: form_obj = BaseModelForm(request.POST) if form_obj.is_valid(): form_obj.save() return redirect(self.get_list_url()) else: return render(request, "stark/add_view.html", locals()) # 视图函数 改 def change_view(self,request,id): BaseModelForm=self.get_model_form() edit_obj=self.model.objects.filter(pk=id).first() if request.method=="GET": form_obj=BaseModelForm(instance=edit_obj) return render(request,"stark/change_view.html",locals()) else: form_obj = BaseModelForm(request.POST,instance=edit_obj) if form_obj.is_valid(): form_obj.save() return redirect(self.get_list_url()) else: return render(request, "stark/change_view.html", locals()) # 视图函数 删 def delete_view(self,request, id): if request.method=="POST": self.model.objects.filter(pk=id).delete() return redirect(self.get_list_url()) list_url=self.get_list_url() return render(request,"stark/delete_view.html",locals()) @property def get_urls(self): temp = [ path("", self.list_view,name="%s_%s_list"%(self.app_label,self.model_name)), path("add/", self.add_view,name="%s_%s_add"%(self.app_label,self.model_name)), re_path("(\d+)/change/", self.change_view,name="%s_%s_change"%(self.app_label,self.model_name)), re_path("(\d+)/delete/", self.delete_view,name="%s_%s_delete"%(self.app_label,self.model_name)), ] return (temp, None, None)class StarkSite: ''' stark全局类 ''' def __init__(self): self._registry = {} def register(self, model, admin_class=None, **options): admin_class = admin_class or ModelStark self._registry[model] = admin_class(model) def get_urls(self): # 动态为注册的模型类创建增删改查URL temp = [] # {Book:ModelAdmin(Book),Publish:ModelAdmin(Publish)} for model, config_obj in self._registry.items(): print("---->", model, config_obj) model_name = model._meta.model_name app_label = model._meta.app_label temp.append( path("%s/%s/" % (app_label,model_name),config_obj.get_urls) ) ''' path("stark/app01/book",BookConfig(Book).list_view) path("stark/app01/book/add",BookConfig(Book).add_view) path("stark/app01/publish",ModelAdmin(Publish).list_view) path("stark/app01/publish/add",ModelAdmin(Publish).add_view) ''' return temp @property def urls(self): return self.get_urls(),None,Nonesite = StarkSite()
stark/service/sites.py
# -*- coding: utf-8 -*-# @Time    : 2019/4/12 11:47# @Author  : xxx# @Email   : xxx@admin.com# @File    : stark.py# @Software: PyCharmfrom stark.service.sites import site,ModelStarkfrom .models import *from django.utils.safestring import mark_safefrom django.forms import ModelForm#自定义模型表单类class BookModelForm(ModelForm):    class Meta:        model=Book        fields="__all__"        error_messages={           "title":{ "required":" 该字段不能为空!"}        }#自定义模型配置类class BookConfig(ModelStark):        #自定义函数列    def show_authors(self,obj=None,header=False):        if header:            return "作者信息"        return " ".join([author.name for author in obj.authors.all()])#自定义显示字段    list_display=["title","price","state","publish",show_authors]#自定义链接字段    list_display_links=["title","price"]#自定义模型表单类的值传给 模型配置类实例对象    model_form_class=BookModelForm# 自定义分页 :每页显示的数据条数    per_page_num=3 # 自定义筛选字段    search_fields=["title","price"]#注册模型类site.register(Book,BookConfig)site.register(Publish)# print(site._registry)
app01/stark.py
from django.contrib import adminfrom django.urls import pathfrom stark.service.sites import siteurlpatterns = [    path('admin/', admin.site.urls),    path('stark/', site.urls),]
urls.py
    
Title

查看数据

添加{
{ table_name }}
{% if show_list.config_obj.search_fields %} {# 注释:如果模型配置类里面没有配置search_fields,就不显示搜索框 #}
{% endif %}
{% for item in show_list.get_header %}
{% endfor %}
{% for item in show_list.get_body %}
{% for info in item %}
{% endfor %}
{% endfor %}
{ { item }}
{ { info }}
{
{ show_list.pagination.page_html|safe }}
stark/templates/stark/list_view.html
class Pagination(object):    def __init__(self, request, current_page, all_data, per_page_num=None, max_page_count=11):        """        封装分页相关数据        :param current_page: 当前页        :param all_count:    分页数据中的数据总条数        :param per_page_num: 每页显示的数据条数        :param max_page_count:  最多显示的页码个数        """        try:            current_page = int(current_page)        except Exception as e:            current_page = 1        if current_page < 1:            current_page = 1        self.current_page = current_page        self.all_count = len(all_data)        self.per_page_num = per_page_num        # 总页码        all_pager, tmp = divmod(self.all_count, per_page_num)        if tmp:            all_pager += 1        self.all_pager = all_pager        self.max_page_count = max_page_count        self.max_page_count_half = int((max_page_count - 1) / 2)        self.request = request        #        import copy        self.params = copy.deepcopy(self.request.GET)    '''     all_count=100    per_page_num =10      current_page        start    end          1                 0      10          2                 10     20          3                 20     30      all_count=100    per_page_num =8     current_page        start    end          1                 0      8          2                 8      16          3                 16     24       表达式:    start= (current_page-1)*per_page_num    end =current_page* per_page_num    '''    @property    def start(self):        return (self.current_page - 1) * self.per_page_num    @property    def end(self):        return self.current_page * self.per_page_num    def page_html(self):        # 如果总页码 < 11个:        if self.all_pager <= self.max_page_count:            pageRange = range(1, self.all_pager + 1)        # 总页码  > 11        else:            # 当前页如果小于页面上最多显示(11-1)/2个页码            if self.current_page <= self.max_page_count_half:                pageRange = range(1, self.max_page_count + 1)            # 当前页大于5            else:                # 页码翻到最后                if (self.current_page + self.max_page_count_half) > self.all_pager:                    pageRange = range(self.all_pager - self.max_page_count + 1, self.all_pager + 1)                else:                    pageRange = range(self.current_page - self.max_page_count_half,                                      self.current_page + self.max_page_count_half + 1)        # 构建分页页码的html        page_html_list = []        self.params["page"] = 1        first_page = '
' % (self.params.urlencode()) page_html_list.append(last_page) return ''.join(page_html_list)
stark/utils/page.py

 

转载于:https://www.cnblogs.com/linux985/p/11101121.html

你可能感兴趣的文章
C# 两个datatable中的数据快速比较返回交集或差集
查看>>
关于oracle样例数据库emp、dept、salgrade的mysql脚本复杂查询分析
查看>>
一些有趣的代码
查看>>
Major Performance Impacts
查看>>
读《图解HTTP》有感-(返回结果的HTTP状态码)
查看>>
操作数栈
查看>>
转:文本分类问题
查看>>
tensorflow_python中文手册
查看>>
Vs2012在Linux应用程序开发(3):加入新平台hi3516
查看>>
adb shell am 的用法
查看>>
实现自动点击
查看>>
MVP开发模式的理解
查看>>
Unity多开的方法
查看>>
File类中的list()和listFiles()方法
查看>>
我的VS CODE插件配置 主要针对.NET和前端插件配置
查看>>
关于js中的事件
查看>>
一致性哈希算法运用到分布式
查看>>
决策树和随机森林->信息熵和条件熵
查看>>
iOS10 UI教程视图和子视图的可见性
查看>>
Maven学习笔记
查看>>